/*
 *  Copyright 2003 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *  
 */
/* "@(#) DDK 1.10.00.21 06-26-03 (ddk-b10)" */
#include <std.h>
#include <tsk.h>  
#include <sem.h>   
#include <gio.h>

#include <csl_dat.h>
#include <csl_cache.h>


#include <fvid.h>
#include <edc.h>
#include <vport.h>
#include <vportcap.h>
#include <vportdis.h>
#include <saa7105.h>
#include <tvp51xx.h>    

#include <evmdm642.h>
#include <evmdm642_capParamsSDTVDefault.h>
#include <evmdm642_disParamsVGADefault.h>
#include "img_proc.h"

VPORT_PortParams EVMDM642_vCapParamsPort 
= EVMDM642_CAP_PARAMS_PORT_EMBEDDED_DEFAULT;

static VPORTCAP_Params EVMDM642_vCapParamsChan 
  = EVMDM642_CAP_PARAMS_CHAN_EMBEDDED_DEFAULT(NTSC720);

static TVP51XX_ConfParams EVMDM642_vCapParamsTVP5146 
  = EVMDM642_CAP_PARAMS_TVP51XX_EMBEDDED_DEFAULT(NTSC601, COMPOSITE, 0);

/* display configuration parameters */
VPORT_PortParams EVMDM642_vDisParamsPort 
  = EVMDM642_DIS_PARAMS_PORT_DEFAULT;

/* The available display modes are: **
** VGA(640x480@60fps)               **
** SVGA(800x600@60fps)              **
** XGA(1024x768@60fps)              */                 

static VPORTDIS_Params EVMDM642_vDisParamsChan 
  = EVMDM642_DIS_PARAMS_CHAN_RGB565_DEFAULT(XGA);

static SAA7105_ConfParams EVMDM642_vDisParamsSAA7105 
  = EVMDM642_DIS_PARAMS_SAA7105_RGB565_DEFAULT(XGA);


#pragma DATA_SECTION(int_mem, ".onchip_image");
unsigned char int_mem[14  * 720];

#define f4_2_0 0
#define f4_2_2 1
#define p 64     //64
#define l_hh 4
#define n_hh p  

#pragma DATA_SECTION(jump_table1, ".onchip_image");
#pragma DATA_SECTION(guide_table1,".onchip_image");
#pragma DATA_SECTION(hh1, ".onchip_image");
#pragma DATA_SECTION(jump_table2, ".onchip_image");
#pragma DATA_SECTION(guide_table2,".onchip_image");
#pragma DATA_SECTION(hh2, ".onchip_image");

#pragma DATA_ALIGN(jump_table1, 128);
#pragma DATA_ALIGN(guide_table1, 128);
#pragma DATA_ALIGN(hh1, 16);

#pragma DATA_ALIGN(jump_table2, 128);
#pragma DATA_ALIGN(guide_table2, 128);
#pragma DATA_ALIGN(hh2, 16);

short   hh1[p * l_hh + 8];  
short   jump_table1[p + 8]; 
short   guide_table1[p + 8];

short   hh2[p * l_hh  + 8];  
short   jump_table2[p + 8]; 
short   guide_table2[p + 8];
   
   
#pragma DATA_SECTION(L2scratch_pad, ".onchip_image");  
#pragma DATA_SECTION(clean,".onchip_image");

                    
#pragma DATA_ALIGN(L2scratch_pad, 128);
#pragma DATA_ALIGN(clean, 16);

unsigned char L2scratch_pad[10*4096];
int q_h, q_v, counter, sign;

unsigned char clean[1024] = {  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};



/* heap IDs defined in the BIOS configuration file */
extern Int EXTERNALHEAP;


#pragma DATA_SECTION(ext_mem, "ext_sect");
unsigned char ext_mem[(1024 * 768) + (512 * 768) + (512 * 768)];


/*
 * ======== main ========
 */
main()
{
    /******************************************************/
    /* open CSL DAT module for fast copy                  */
    /******************************************************/
    CSL_init();                                             
    CACHE_clean(CACHE_L2ALL, 0, 0);
    CACHE_setL2Mode(CACHE_128KCACHE);       
    CACHE_enableCaching(CACHE_EMIFA_CE00);
    CACHE_enableCaching(CACHE_EMIFA_CE01);
    DAT_open(DAT_CHAANY, DAT_PRI_LOW, DAT_OPEN_2D);

}

/*
 * ======== tskVideoLoopback ========
 * video loopback function.
 */
void tskVideoLoopback()
{
    Int status;
    FVID_Handle disChan; 
    Int frames = 0;
    FVID_Frame *disFrameBuf;
    Int numLinesDis = EVMDM642_vDisParamsChan.imgVSizeFld1;
    Int numLinesCap = EVMDM642_vCapParamsChan.fldYStop1 -
       EVMDM642_vCapParamsChan.fldYStrt1+1;
       
   /*--------------------------------------------------------------------*/
   /* IMAGE declarartions for even and odd fields. IMAGE declarations    */
   /* for output image. SCRATCH_PAD is a structure that maintains info-  */
   /* rmation about temporary scratch space for algorithm use.           */
   /*--------------------------------------------------------------------*/
                     
   IMAGE in_image_luma_ev;
   IMAGE in_image_Cr_ev;
   IMAGE in_image_Cb_ev; 
   IMAGE in_image_luma_od;
   IMAGE in_image_Cr_od;
   IMAGE in_image_Cb_od;
   IMAGE out_image;
   SCRATCH_PAD scratch_pad;
   
   char *temp;
   unsigned int id0; 
   unsigned char *ext_y,     *ext_cr, *ext_cb;
  
  
   short        *vpatch1, * hpatch1; 
   int          display_width, display_height; 
   int          in_pic_width, in_pic_height;
   
   int q_h     =  32;  //131;
   int q_v     =  32;  //54;
   int counter = 0;
   int sign    = 1;
   
    
    Int numLines = (numLinesDis > numLinesCap) ? numLinesCap : numLinesDis;

    Int i;
    FVID_Handle capChan; 
    FVID_Frame *capFrameBuf;
    Int capLinePitch = EVMDM642_vCapParamsChan.fldXStop1 - 
       EVMDM642_vCapParamsChan.fldXStrt1+1;
    Int disLinePitch = EVMDM642_vDisParamsChan.imgHSizeFld1;

 
    numLines *= 2; /* both fields */
    /******************************************************/
    /* allocate both capture and display frame buffers    */
    /* in external heap memory                            */
    /******************************************************/
        EVMDM642_vCapParamsChan.segId = EXTERNALHEAP;
        EVMDM642_vDisParamsChan.segId = EXTERNALHEAP;
        EVMDM642_vDisParamsSAA7105.hI2C = EVMDM642_I2C_hI2C;
        EVMDM642_vCapParamsTVP5146.hI2C = EVMDM642_I2C_hI2C;

    /******************************************************/
    /* initialization of capture driver                   */
    /******************************************************/
    capChan = FVID_create("/VP0CAPTURE/A/0", 
            IOM_INPUT, &status, (Ptr)&EVMDM642_vCapParamsChan, NULL);
    /******************************************************/
    /* initialization of display driver                   */
    /******************************************************/
    disChan = FVID_create("/VP2DISPLAY", IOM_OUTPUT, 
        &status, (Ptr)&EVMDM642_vDisParamsChan, NULL);

    
    /******************************************************/
    /* configure video encoder & decoder                  */
    /******************************************************/
    FVID_control(disChan, VPORT_CMD_EDC_BASE + EDC_CONFIG, 
        (Ptr)&EVMDM642_vDisParamsSAA7105);
    FVID_control(capChan, VPORT_CMD_EDC_BASE + EDC_CONFIG, 
        (Ptr)&EVMDM642_vCapParamsTVP5146);

    


    /******************************************************/
    /* start capture & display operation                  */    
    /******************************************************/
    FVID_control(disChan, VPORT_CMD_START, NULL);
    FVID_control(capChan, VPORT_CMD_START, NULL);

    
    /********************************************************/
    /* request a frame buffer from display & capture driver */
    /********************************************************/
    FVID_alloc(disChan, &disFrameBuf);

    FVID_alloc(capChan, &capFrameBuf);

    frames ++;
    
    in_image_luma_ev.img_cols = capLinePitch;
    in_image_luma_ev.img_rows = numLines/2;
    in_image_luma_od.img_cols = capLinePitch;
    in_image_luma_od.img_rows = numLines/2;
  
    in_image_Cr_ev.img_cols = in_image_Cb_ev.img_cols = capLinePitch/2;
    in_image_Cr_ev.img_rows = in_image_Cb_ev.img_rows = numLines/2;
    in_image_Cr_od.img_cols = in_image_Cb_od.img_cols = capLinePitch/2;
    in_image_Cr_od.img_rows = in_image_Cb_od.img_rows = numLines/2;
    
  
    scratch_pad.ext_data   = (char *) (ext_mem);
    scratch_pad.ext_size   = sizeof(ext_mem);
    scratch_pad.int_data   = (char *) int_mem;
    scratch_pad.int_size   = sizeof(int_mem);
    
    for (i = 0; i < 3; i++)
    {
        
        memset(disFrameBuf->frame.rpFrm.buf, 0x0, 2 * disLinePitch * 768);
        CACHE_clean(CACHE_L2ALL, 0, 0);
        FVID_exchange(disChan, &disFrameBuf);
    }
       
    
    while(1){/* loop forever */
        /* copy data from capture buffer to display buffer */
        /***************************************************/
            in_image_luma_ev.img_data = (unsigned char *) capFrameBuf->frame.iFrm.y1;
            in_image_Cr_ev.img_data   = (unsigned char *) capFrameBuf->frame.iFrm.cb1;
            in_image_Cb_ev.img_data   = (unsigned char *) capFrameBuf->frame.iFrm.cr1;
            in_image_luma_od.img_data =  in_image_luma_ev.img_data + capLinePitch;
            in_image_Cr_od.img_data   =  in_image_Cr_ev.img_data   + (capLinePitch/2);
            in_image_Cb_od.img_data   =  in_image_Cb_ev.img_data   + (capLinePitch/2);
            out_image.img_data        =  ext_mem;
            out_image.img_cols        =  capLinePitch;
            out_image.img_rows        =  (numLines >> 1); 
            
            
            color_convert(&in_image_luma_ev, &in_image_Cr_ev, &in_image_Cb_ev, 
                  &in_image_luma_od, &in_image_Cr_od, &in_image_Cb_od,
                  &out_image,     &scratch_pad,  disLinePitch);
                  
            
                  
            temp = (char *) L2scratch_pad;
 
            
		    for (i=0; i  < 40; i++) 
		    {
		        id0 = DAT_copy(clean, &temp[i*1024], 1024);
		        DAT_wait(id0);
		    }
	
	
		    counter ++; 
                
		    if ((counter% 4) == 0)
		    {
		        
		        q_h = (q_h - (sign * 2));
		        q_v = (q_v - (sign * 2));      
		        
		        if ((q_h <= 5) || (q_v <= 5))
		        {         
		            sign = sign * -1;
		            
		        }
		        
		        if ((q_h >= 280) || (q_v >= 280))
		        {           
		            sign = sign * -1;		           
		        }
		        		                               
		    }
		    
		    hpatch1 = jump_table1; 
		    vpatch1 = guide_table2;
		   
		    filt_gen(p, q_h, hh1, guide_table1, jump_table1);
		    filt_gen(p, q_v, hh2, guide_table2, jump_table2); 
		    
		    
		     
		    /*----------------------------------------------------------------------*/
		    /* Configure capture hardware for square pixel and display hardware for */
		    /* RGB data of packed 565 format.                                       */
		    /*----------------------------------------------------------------------*/
		  
		    display_width  = 1024;
		    in_pic_width   = 720;
		    display_height = 768; 
		    in_pic_height  = 240;
		    
		    ext_y  = ext_mem;
            ext_cr = ext_y   + (720 * 240);
            ext_cb = ext_cr  + (360 * 240);
		
		  /*------------------------------------------------------------------*/
		  /*  The current set of input and output pointers are obtained by    */
		  /* calls to the getFrame and putFrame routine.                      */
		  /*------------------------------------------------------------------*/
		      
		  /*------------------------------------------------------------------*/
		  /* The input frame pointer contains six pointers, two each for the  */
		  /* Y, Cr and Cb data. These pointers are used to copy/capture data  */
		  /* (both fields) from daughter card to SDRAM (external memory)      */ 
		  /* by firing DMA transfers from these locations to arrays in        */
		  /* external memory. Wait on the transfer id of the last transfer    */
		  /* id to make sure tyhat transfers completed.                       */
		  /*------------------------------------------------------------------*/
		            
		      scale_2d_ycrcb (
		        f4_2_2,         /* 4:4:4 == 2, 4:2:2 == 1, 4:2:0 == 0            */
		  
		        p,              /* numerator for horizontal scale factor p/q     */
		        q_h,            /* denominator for horizontal scale factor p/q   */
		
		        hpatch1,        /* stride table for horizontal scaling jumps     */
		        hh1,            /* pntr to horz filter bank                      */
		        l_hh,           /* number of taps in each horz filter            */
		        n_hh,           /* number of filters in horz filter bank         */
		
		        p,              /* numerator for vertical scale factor p/q       */
		        q_v,            /* denominator for vertical scale factor p/q     */
		
		        vpatch1,        /* stride table for vertical scaling jumps       */
		        hh2,            /* pntr to vert filter bank                      */
		        l_hh,           /* number of taps in each vert filter            */
		        n_hh,           /* number of filters in vert filter bank         */
		
		        in_pic_height,  /* height of picture in Pixels multiple of 2     */
		        in_pic_width,   /* width  of picture in Pixels multiple of 8     */
		    
		        display_height, /* height of picture in Pixels multiple of 2     */
		        display_width,  /* width  of picture in Pixels multiple of 8     */
		
		        ext_y,       /* pntr to input image planar y values  */
		        ext_cr,      /* pntr to input image planar cr values */
		        ext_cb,      /* pntr to input image planar cb values */
		        L2scratch_pad,  /* temp space for internal buffers s    */
		                        /* aligned to a double boundary         */
		        (unsigned char *) disFrameBuf->frame.rpFrm.buf 
		        ); /* pntr to output image, scaled in color*/  
		        
       
        FVID_exchange(capChan, &capFrameBuf);
        

        CACHE_clean(CACHE_L2ALL, 0, 0);
        
        
        FVID_exchange(disChan, &disFrameBuf); 
        
        frames ++;              
   }
}
